
-- thanks to the creator of StrandedRP for this section of code! you made my life 100% easier!

//Locals
local PlayerMeta = FindMetaTable("Player")
local EntityMeta = FindMetaTable("Entity")
/*---------------------------------------------------------
  Process system
---------------------------------------------------------*/
Processes = {}

//Registry
function RegisterProcess(name,tbl)
         Processes[name] = tbl
end

//Handle think hooks
GM.ProcessThinkHookTable = {}
function GM.ProcessThink()
         local GM = GAMEMODE
         for k,v in pairs(GM.ProcessThinkHookTable) do
             local think;
             if v.Think then think = v:Think() end
             
             local basethink = v:BaseThink()
             
             if think or basethink then
                if v.Owner and v.Owner != NULL and v.Owner:IsValid() then 
                   v.Owner:Freeze(false)
                   --v.Owner:StopProcessBar()
                   v.Owner.InProcess = false
                   v.Owner:ChatPrint("Cancelled.")
                end

                v.IsStopped = true
                timer.Destroy("ProcessTimer_"..v.TimerID)
                GM.RemoveProcessThink(v)
             end
         end
end

hook.Add("Think","USRP_ProcessThinkHooks",GM.ProcessThink)

function GM.AddProcessThink(tbl)
         table.insert(GAMEMODE.ProcessThinkHookTable,tbl)
end

function GM.RemoveProcessThink(tbl)
         for k,v in pairs(GAMEMODE.ProcessThinkHookTable) do
             if v == tbl then
                table.remove(GAMEMODE.ProcessThinkHookTable,k)
             end
         end
end

//Actual processing
function PlayerMeta:DoProcess(name,time,data)
         if self.InProcess then
            self:ChatPrint("You can't do this much at once.")
         return end
         
         //Need seperate instance
         self.ProcessTable = table.Merge(table.Copy(Processes[name]),table.Copy(Processes.BaseProcess))
         self.ProcessTable.Owner = self
         self.ProcessTable.Time = time
         self.ProcessTable.TimerID = self:UniqueID()
         if data then self.ProcessTable.Data = data end

         self.InProcess = true

         if self.ProcessTable.OnStart then self.ProcessTable:OnStart() end
         
         //Start think
         GAMEMODE.AddProcessThink(self.ProcessTable)

         timer.Create("ProcessTimer_"..self:UniqueID(),time, 1, GAMEMODE.StopProcess, self)
end


function GM.StopProcess(pl)
         //Run stop
         local bool = pl.ProcessTable:BaseStop()
         if pl.ProcessTable.OnStop then pl.ProcessTable:OnStop() end
         //Stop think
         if pl.ProcessTable.Think then GAMEMODE.RemoveProcessThink(pl.ProcessTable) end
         
         pl.InProcess = false
         pl.ProcessTable = nil
end

/*---------------------------------------------------------
  Base process
---------------------------------------------------------*/
local PROCESS = {}

-- Not sure what this does, reordered checks to attemt to fix NULL entity error on player disconnect.
function PROCESS:BaseThink()
	if !self.Owner:IsValid() or !self.Owner:IsConnected() then
		return true
	end
	
	if !self.Owner:Alive() or !self.Owner or self.Owner == NULL then
		return true
	end
end

function PROCESS:BaseStop()
         if !self.Owner:Alive() or !self.Owner or self.Owner == NULL then return false end
         if !self.Owner:IsValid() then return false end
         
         --self.Owner:StopProcessBar()
         return true
end

Processes.BaseProcess = PROCESS


/*---------------------------------------------------------
  Mining
---------------------------------------------------------*/
local PROCESS = {}

function PROCESS:OnStart()
         --self.Owner:MakeProcessBar("Mining",self.Time)
		 self.Owner:ChatPrint("Mining.....")
         self.Owner:Freeze(true)
         self.StartTime = CurTime()
         
         self:PlaySound()
         if !self.Data.Entity.Uses then self.Data.Entity.Uses = 250 end
end

function PROCESS:PlaySound()
         if CurTime() - self.StartTime > self.Time then return end
         
         self.Owner:GetActiveWeapon():SendWeaponAnim(ACT_VM_HITCENTER)
         self.Owner:EmitSound(Sound("physics/glass/glass_bottle_impact_hard"..tostring(math.random(1,3))..".wav"))
         
         timer.Simple(1.5,self.PlaySound,self)
end

function PROCESS:OnStop()
         local num = math.random(1,100)
			
			
			
         if num < self.Data.Chance + self.Owner:Skill_Get("mining") then
            local num2 = math.random(1,3)
            local num3 = math.random(self.Data.MinAmount,self.Data.MaxAmount)
			local miningskill = self.Owner:Skill_Get("mining")


			   
            if num2 == 1 and miningskill >= 25 then
               self.Owner:Resources_Add("iron",num3)
               self.Owner:ChatPrint("Iron ("..num3.."x)")
			   self.Owner:Skill_Add("mining",1)
			   
			elseif num2 == 2 and miningskill >= 50 then
			   self.Owner:Resources_Add("titanium",num3)
               self.Owner:ChatPrint("Titanium ("..num3.."x)")
			   self.Owner:Skill_Add("mining",1)
			else
			   self.Owner:Resources_Add("copper",num3)
               self.Owner:ChatPrint("Copper ("..num3.."x)")
			   self.Owner:Skill_Add("mining",1)
            end

            --self.Owner:Skill_Add("mining", 1)
            self.Owner:EmitSound(Sound("items/ammo_pickup.wav"))
            if self.Data.Entity then self.Data.Entity.Uses = self.Data.Entity.Uses - num3 end
			self.Owner:ChatPrint("Your Mining Skill Has Increased To "..self.Owner:Skill_Get("mining").."!")
         else
            self.Owner:ChatPrint("Failed.")
         end
         
		 	if miningskill == 25 then
			self.Owner:ChatPrint("You Have Unlocked Mining Iron!")
			elseif miningskill == 50 then
			self.Owner:ChatPrint("You Have Unlocked Mining Titanium!")
			end
			
         self.Owner:Freeze(false)
         
         if self.Data.Entity != NULL then
            if self.Data.Entity.Uses <= 0 then
               self.Data.Entity:Fadeout()
            end
         end
end

RegisterProcess("Mining",PROCESS)

/*---------------------------------------------------------
  Smelting Copper
---------------------------------------------------------*/
local PROCESS = {}

function PROCESS:OnStart()
         --self.Owner:MakeProcessBar("Mining",self.Time)
		 if self.Owner:Resources_Has("copper") then
		 self.Owner:ChatPrint("Smelting Copper Ore.....")
         self.Owner:Freeze(false)
         self.StartTime = CurTime()         
         self:PlaySound()
		 else
			self.Owner:ChatPrint("You Dont Have Any Copper Ore!")
         end
end

function PROCESS:PlaySound()
         if CurTime() - self.StartTime > self.Time then return end
         
         self.Owner:GetActiveWeapon():SendWeaponAnim(ACT_VM_PULLPIN)
         --self.Owner:EmitSound(Sound("ambient/gas/steam2.wav"))
         
         timer.Simple(1.5,self.PlaySound,self)
		 --t-imer.Simple( 1.5,  self.Owner:StopSound("ambient/gas/steam2.wav" ))
		 
end

 


function PROCESS:OnStop()
			self.Owner:StopSound("ambient/gas/steam2.wav")
         local num = math.random(1,100)
		 
	
           
			if self.Owner:Resources_Has("copper") then
				local num3 = 1

            
				self.Owner:Resources_Take("copper",1)
				self.Owner:Resources_Add("copper_bar",1)
				self.Owner:ChatPrint("Copper Bar (1x)")
            

				self.Owner:Skill_Add("smelting", math.Clamp(math.Round(50 / self.Owner:Skill_Get("smelting")),1 , 1000))
				self.Owner:EmitSound(Sound("items/ammo_pickup.wav"))
				--if self.Data.Entity then self.Data.Entity.Uses = self.Data.Entity.Uses - num3 end
				self.Owner:ChatPrint("Your Smelting Skill Has Increased To "..self.Owner:Skill_Get("smelting").."!")
			else
					self.Owner:ChatPrint("You Dont Have Any Copper Ore!")
			end
		
         
         self.Owner:Freeze(false)
         
         --if self.Data.Entity != NULL then
            --if self.Data.Entity.Uses <= 0 then
              -- self.Data.Entity:Fadeout()
           -- end
         --end
end

RegisterProcess("SmeltCopper",PROCESS)

/*---------------------------------------------------------
  Smelting Iron
---------------------------------------------------------*/
local PROCESS = {}

function PROCESS:OnStart()
         --self.Owner:MakeProcessBar("Mining",self.Time)
		 if self.Owner:Resources_Has("iron") then
		 self.Owner:ChatPrint("Smelting Iron Ore.....")
         self.Owner:Freeze(false)
         self.StartTime = CurTime()         
         self:PlaySound()
		 else
			self.Owner:ChatPrint("You Dont Have Any Iron Ore!")
         end
end

function PROCESS:PlaySound()
         if CurTime() - self.StartTime > self.Time then return end
         
         self.Owner:GetActiveWeapon():SendWeaponAnim(ACT_VM_PULLPIN)
         --self.Owner:EmitSound(Sound("ambient/gas/steam2.wav"))
         
         timer.Simple(1.5,self.PlaySound,self)
		 --t-imer.Simple( 1.5,  self.Owner:StopSound("ambient/gas/steam2.wav" ))
		 
end

 


function PROCESS:OnStop()
			self.Owner:StopSound("ambient/gas/steam2.wav")
         local num = math.random(1,100)
		 
	
           
			if self.Owner:Resources_Has("iron") then
				local num3 = 1

            
				self.Owner:Resources_Take("iron",1)
				self.Owner:Resources_Add("iron_bar",1)
				self.Owner:ChatPrint("Iron Bar (1x)")
            

				self.Owner:Skill_Add("smelting", math.Clamp(math.Round(50 / self.Owner:Skill_Get("smelting")),1 , 1000))
				self.Owner:EmitSound(Sound("items/ammo_pickup.wav"))
				self.Owner:ChatPrint("Your Smelting Skill Has Increased To "..self.Owner:Skill_Get("smelting").."!")
			else
					self.Owner:ChatPrint("You Dont Have Any Iron Ore!")
			end
		
         
         self.Owner:Freeze(false)
         

end

RegisterProcess("SmeltIron",PROCESS)

/*---------------------------------------------------------
  Smelting Titanium
---------------------------------------------------------*/
local PROCESS = {}

function PROCESS:OnStart()
         --self.Owner:MakeProcessBar("Mining",self.Time)
		 if self.Owner:Resources_Has("titanium") then
		 self.Owner:ChatPrint("Smelting Titanium Ore.....")
         self.Owner:Freeze(false)
         self.StartTime = CurTime()         
         self:PlaySound()
		 else
			self.Owner:ChatPrint("You Dont Have Any Titanium Ore!")
         end
end

function PROCESS:PlaySound()
         if CurTime() - self.StartTime > self.Time then return end
         
         self.Owner:GetActiveWeapon():SendWeaponAnim(ACT_VM_PULLPIN)
         --self.Owner:EmitSound(Sound("ambient/gas/steam2.wav"))
         
         timer.Simple(1.5,self.PlaySound,self)
		 --t-imer.Simple( 1.5,  self.Owner:StopSound("ambient/gas/steam2.wav" ))
		 
end

 


function PROCESS:OnStop()
			self.Owner:StopSound("ambient/gas/steam2.wav")
         local num = math.random(1,100)
		 
	
           
			if self.Owner:Resources_Has("titanium") then
				local num3 = 1

            
				self.Owner:Resources_Take("titanium",1)
				self.Owner:Resources_Add("titanium_bar",1)
				self.Owner:ChatPrint("Titanium Bar (1x)")
            

				self.Owner:Skill_Add("smelting", math.Clamp(math.Round(50 / self.Owner:Skill_Get("smelting")),1 , 1000))
				self.Owner:EmitSound(Sound("items/ammo_pickup.wav"))
				self.Owner:ChatPrint("Your Smelting Skill Has Increased To "..self.Owner:Skill_Get("smelting").."!")
			else
					self.Owner:ChatPrint("You Dont Have Any Titanium Ore!")
			end
		
         
         self.Owner:Freeze(false)
         

end

RegisterProcess("SmeltTitanium",PROCESS)


